package dao

import (
	"github.com/go-redis/redis"
	"go-learn/global"
	"go-learn/model"
	"strconv"
)

/*
	添加玩家成绩
*/
func AddPlayer(players []model.Player) error {
	var members []redis.Z
	var pairs []string
	// 转化为map后加入hash表中
	for _, player := range players {
		fields := PlayerToMap(player)
		if err := HMSet(player.Id, fields); err != nil {
			return err
		}
		members = append(members, redis.Z{Score: player.Score, Member: player.Id})
		pairs = append(pairs, player.Name, player.Id)
	}
	// 将成绩和id插入zset用作排序
	if err := ZAdd(global.KeyName, members); err != nil {
		return err
	}
	// 将用户id和姓名存入string用作查询
	return MSet(pairs)
}

/*
	获取排行榜并分页
*/
func GetRankList(page, size int64) ([]model.Player, error) {
	// 先从zset表拿到id排名
	members, err := ZRevRangeWithScores(global.KeyName, page, size)
	if err != nil {
		return nil, err
	}
	// 再根据id从hash表查询具体数据
	var players []model.Player
	for _, z := range members {
		data, err := HGetAll(z.Member.(string))
		if err != nil {
			return nil, err
		}
		player := MapToPlayer(data)
		players = append(players, player)
	}
	return players, err
}

/*
	获取指定分数区间的排行榜并分页
*/
func GetRankListByScore(min, max string, page, size int64) ([]model.Player, error) {
	// 先从zset表拿到id排名
	members, err := ZRevRangeByScoreWithScores(global.KeyName, min, max, page, size)
	if err != nil {
		return nil, err
	}
	// 再根据id从hash表查询具体数据
	var players []model.Player
	for _, member := range members {
		data, err := HGetAll(member)
		if err != nil {
			return nil, err
		}
		player := MapToPlayer(data)
		players = append(players, player)
	}
	return players, err
}

/*
	查询指定人的排名
*/
func GetRankByName(name string) (int64, error) {
	id, err := Get(name)
	if err != nil {
		return 0, err
	}
	return ZRevRank(global.KeyName, id.(string))
}
func PlayerToMap(player model.Player) map[string]interface{} {
	fields := make(map[string]interface{})
	fields["id"] = player.Id
	fields["name"] = player.Name
	fields["score"] = player.Score
	return fields
}
func MapToPlayer(fields map[string]string) model.Player {
	score, _ := strconv.ParseFloat(fields["score"], 64)
	player := model.Player{Id: fields["id"], Name: fields["name"], Score: score}
	return player
}
